
/// 接口工具函数:
function setSlectionMode(selectByModel) {
    /** 设置对象选择模式
     *
     * @selectByModel{boolean} - 是否按对象选择
     * */
    isSelectByDisease = !selectByModel;
}

function setModelOpacity(value) {
    /** 设置模型透明度
     *
     * @value{float} - 透明度(0-1之间的浮点数)
     */
    modelObjects.forEach(function (item, index) {
        item.material.opacity = value;
    });
}

function showHideSpanPave(index, visible) {
    /** 设置上部面层可见性
     *
     * @index{int} - 桥跨号(1-54之间)
     * @visible{boolean} - 显示或不显示
     */
    names = [
        formatIndexNumber(index) + '_guard',
        formatIndexNumber(index) + '_pave'
    ];
    modelObjects.forEach(function (item, index) {
        names.forEach(function (name, j) {
            if (item.name.indexOf(name) > 0) {
                item.visible = visible;
            }
        })
    })
}

function showHideSpanBeam(index, visible) {
    /** 设置上部结构梁可见性
     *
     * @index{int} - 桥跨号(1-54之间)
     * @visible{boolean} - 显示或不显示
     */
    names = [
        formatIndexNumber(index) + '_span'
    ];
    modelObjects.forEach(function (item, index) {
        names.forEach(function (name, j) {
            if (item.name.indexOf(name) > 0) {
                item.visible = visible;
            }
        })
    })
}

function showHidePier(index, visible) {
    /** 设置桥墩可见性
     *
     * @index{int} - 墩号(0-54之间)
     * @visible{boolean} - 显示或不显示
     */
    names = [
        formatIndexNumber(index) + '_pier'
    ];
    modelObjects.forEach(function (item, index) {
        names.forEach(function (name, j) {
            if (item.name.indexOf(name) > 0) {
                item.visible = visible;
            }
        })
    })
}

function selectObject(newSelectedObject) {
    /** 选择对象
     *
     * @newSelectedObject{int} - 新选择的对象
     */
    if (selectedOjbect !== undefined){
        selectedOjbect.material = selectedOjbect.oldMaterial;
    }
    selectedOjbect = newSelectedObject;
    selectedMaterial= selectedOjbect.material.clone();
    //selectedMaterial.color = 0xF5DEB3;
    selectedMaterial.transparent = true;
    var opacity = selectedMaterial.opacity - 0.4;
    if (opacity<0)
        opacity = 0.8;
    selectedMaterial.opacity = opacity;
    selectedOjbect.material = selectedMaterial;
    console.log('选择了对象:' + selectedOjbect.name);
}

function jumpToObject(aobject) {
    /** 跳转到对象
     *
     * @aobject - 一个对象
     */
    var delta = camera.position.clone().sub(controls.target).normalize().multiplyScalar(40);
    controls.target.copy(aobject.geometry.boundingSphere.center);
    camera.position.copy(delta.add(controls.target));
    controls.update();
}

function jumpToSpan(index) {
    /** 跳转到第n跨
     *
     * @index{int} - 第n跨
     */
    var site = formatIndexNumber(index) + '_span'
    for (var i = 0; i < modelObjects.length; ++i){
        if (modelObjects[i].name.indexOf(site) === 1){
            jumpToObject(modelObjects[i]);
            break;
        }
    }
}

function jumpToPier(index) {
    /** 跳转到第n墩
     *
     * @index{int} - 第n墩
     */
    var site = formatIndexNumber(index) + '_pier_column'
    for (var i = 0; i < modelObjects.length; ++i){
        if (modelObjects[i].name.indexOf(site) === 1){
            jumpToObject(modelObjects[i]);
            break;
        }
    }
}

function jumpToDisease(name) {
    /** 跳转到病害
     *
     * @name{string} - 病害名称
     */
    for (var i = 0; i < diseaseObjects.length; ++i){
        if (diseaseObjects[i].name === name){
            jumpToObject(diseaseObjects[i]);
            break;
        }
    }
}











// -----------------------------------------------------------------------------------------------------------------
// 辅助工具函数
function formatIndexNumber(index) {
    if (index < 10){
        return "0" + index;
    }
    return index.toString();

}

/// 其它实现
var object3d_el = undefined;
var container, stats, controls;
var camera, scene, renderer, light;
var material, selectedMaterial;
var raycaster;
var mouse;
var modelObjects = [];
var diseaseObjects = [];
var selectedOjbect;
var reflectionCube;
var isSelectByDisease = true;

function threeInit() {
    object3d_el = document.getElementById('three3d');
    const width = object3d_el.offsetWidth;
    const height = object3d_el.offsetHeight;
    console.log(width);
    console.log(height);
    container = object3d_el;
    camera = new THREE.PerspectiveCamera(45, width / height, 1, 20000 );
    scene = new THREE.Scene();
    raycaster = new THREE.Raycaster();
    mouse = new THREE.Vector2();

    createCubeMap();

    material = new THREE.MeshPhongMaterial( { color:0xd0d0d0, transparent: true, opacity:0.15, side: THREE.DoubleSide});
    selectedMaterial = new THREE.MeshPhongMaterial( { color: 0xF5DEB3, transparent: true, opacity:0.8, side: THREE.DoubleSide});
    // stats
    stats = new Stats();
    container.appendChild( stats.dom );
    // model
    var manager = new THREE.LoadingManager();
    var objloader = new THREE.OBJLoader( manager );
    objloader.load( '../asset/models/obj/all_in_one_zsht.obj', function( object ) {
        modelObjects = object.children;
        modelObjects.forEach(function (item, index) {
            item.material = material;
            item.oldMaterial = item.material;
        })
        scene.add( object );
    } );
    var mtlLoader = new THREE.MTLLoader();
    mtlLoader.setPath( '../asset/models/obj/' );
    mtlLoader.load( 'disease.mtl', function( materials ) {
        materials.preload();
        objloader.setMaterials( materials );
        objloader.load( '../asset/models/obj/disease.obj', function( object ) {
            diseaseObjects = object.children;
            diseaseObjects.forEach(function (item, index) {
                item.oldMaterial = item.material;
            })
            scene.add( object );
        } );
    });

    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( width, height );
    container.appendChild( renderer.domElement );
    // controls, camera
    controls = new THREE.OrbitControls( camera, renderer.domElement );
    controls.target.set( 30, 12, 0 );
    camera.position.set( 20, 18, 28 );
    controls.update();
    window.addEventListener( 'resize', onWindowResize, false );
    document.addEventListener( 'mousedown', onDocumentMouseDown, false );
    initLight();
    animate();
}

function onDocumentMouseDown( event ) {
    if (event.which !== 3)
        return;

    event.preventDefault();

    mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;

    raycaster.setFromCamera( mouse, camera );

    var objects;
    if (isSelectByDisease) {
        objects = diseaseObjects;
    } else {
        objects = modelObjects;
    }
    var intersects = raycaster.intersectObjects( objects );

    if ( intersects.length > 0 ) {
        for (var i=0; i<intersects.length; ++i){
            if (intersects[i].object.visible){
                selectObject(intersects[i].object);
                break;
            }
        }
    }
}

function createCubeMap() {
    var path = "../asset/textures/cube/skybox/";
    var format = '.jpg';
    var urls = [
        path + 'px' + format, path + 'nx' + format,
        path + 'py' + format, path + 'ny' + format,
        path + 'pz' + format, path + 'nz' + format
    ];
    reflectionCube = new THREE.CubeTextureLoader().load( urls );
    reflectionCube.format = THREE.RGBFormat;
    scene.background = reflectionCube;
}

/**
 * 初始化灯光
 */
function initLight() {
    //*
    //环境光，没有方向，任意方向的发射光线
    var ambient = new THREE.AmbientLight(0xffeedd);
    //环境光强度
    ambient.intensity = 0.3;
    //场景加入环境光
    scene.add(ambient);
    //*/
    //方向光，颜色十六进制表示 0xffeedd
    var directionalLight = new THREE.DirectionalLight(0xffeedd);
    //设置方向光的来源点
    directionalLight.position.set(100, 1000, 1000).normalize();
    scene.add(directionalLight);
    //方向光，颜色十六进制表示 0xffeedd
    var directionalLight = new THREE.DirectionalLight(0xffeedd);
    //设置方向光的来源点
    directionalLight.position.set(100, -1000, -1000).normalize();
    scene.add(directionalLight);
}

function onWindowResize() {
    if (object3d_el)
    {
        let width=parseFloat(object3d_el.offsetWidth);
        let height=parseFloat(object3d_el.offsetHeight);

        camera.aspect = width / height;
        camera.updateProjectionMatrix();

        renderer.setSize( width, height );
    }
}

function animate() {
    requestAnimationFrame( animate );
    stats.update();
    render();
}
function render() {
    renderer.render( scene, camera );
}
